package ffprobe

import (
	"errors"
	"fmt"
	"github.com/gogf/gf/v2/util/gconv"
	"log"
)

// Streams 获取视频流列表
func (p *SFFProbe) Streams() ([]map[string]interface{}, error) {
	// 获取视频内容
	if err := p.Parse(); err != nil {
		return nil, err
	}
	// 获取流列表
	stream, ok := p.parse[`streams`]
	if !ok {
		return nil, errors.New(`Streams 数据不存在`)
	}
	var (
		streams    = stream.([]interface{})
		streamMaps = make([]map[string]interface{}, 0)
	)
	// 格式化结果
	for _, item := range streams {
		streamMaps = append(streamMaps, item.(map[string]interface{}))
	}
	return streamMaps, nil
}

// CodecMap 按文件流类型返回数据字典
func (p *SFFProbe) CodecMap() (map[string]map[string]interface{}, error) {
	streamsMaps, err := p.Streams()
	if err != nil {
		return nil, err
	}

	// 处理数据
	streamsMap := make(map[string]map[string]interface{})
	for _, item := range streamsMaps {
		if v, ok := item[`codec_type`]; ok {
			streamsMap[v.(string)] = item
		}
	}
	return streamsMap, nil
}

// CodecStream 根据文件流类型获取流信息
func (p *SFFProbe) CodecStream(codecType string, pointer interface{}) error {
	// 获取流类型字典
	streamsMap, err := p.CodecMap()
	if err != nil {
		return err
	}
	stream, ok := streamsMap[codecType]
	if !ok {
		return fmt.Errorf(`%s流类型不存在`, codecType)
	}
	return gconv.Struct(stream, pointer)
}

// VideoCodecStream 视频流内容
func (p *SFFProbe) VideoCodecStream() (*VideoStream, error) {
	// 转换视频流
	stream := &VideoStream{}
	if err := p.CodecStream(`video`, &stream); err != nil {
		return nil, fmt.Errorf(`扫描StreamMapdao到VideoStream失败 %w`, err)
	}
	return stream, nil
}

// AudioCodecStream 获取视频音频流详情
func (p *SFFProbe) AudioCodecStream() (*AudioStream, error) {
	// 检查音频流
	stream := &AudioStream{}
	if err := p.CodecStream(`audio`, stream); err != nil {
		return nil, fmt.Errorf(`扫描StreamMapdao到AudioStream失败 %w`, err)
	}
	return stream, nil
}

// MustVideoStream 获取视频流信息
func (p *SFFProbe) MustVideoStream() *VideoStream {
	stream, err := p.VideoCodecStream()
	if err != nil {
		log.Fatalln(err)
	}
	return stream
}

// Width 视频宽度
func (p *SFFProbe) Width() int {
	if item := p.MustVideoStream(); item != nil {
		return item.Width
	}
	return 0
}

// Height 视频高度
func (p *SFFProbe) Height() int {
	if item := p.MustVideoStream(); item != nil {
		return item.Height
	}
	return 0
}
